home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / graphicgems4.lha / GemsIV / outcode / xf1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-06  |  3.4 KB  |  145 lines

  1. /* transform, clip test, and project a vertex list */
  2.  
  3. /* oflo and division traps should be disabled, by the way */
  4.  
  5. #define FI(x)    (*(int *)&x)
  6.  
  7. /********************************************************/
  8. xform_ctp(vc, vpi, vpo, visiz, vosiz, mtx, prj, pf, pa)
  9. int vc    ;    /* vertex count */
  10. int visiz;    /* input vertex array stride */
  11. int vosiz;    /* output vertex array stride */
  12. int *pf;    /* flag array */
  13. int *pa;    /* 2 element - global or_flag, and_flag */
  14. float *vpi, *vpo, *mtx, *prj;
  15. {
  16. register int flag, flag_or, flag_and;
  17. register int ti0, s, t, u;
  18. register int sign = 0x80000000;
  19.  
  20. /* flpt registers, total 32 */
  21. register float xx, xy, xz, xw;        /* transformation matrix */
  22. register float yx, yy, yz, yw;
  23. register float zx, zy, zz, zw;
  24. register float wx, wy, wz, ww;
  25. register float xo, yo, zo, wo;        /* output vertex */
  26. register float xs, xt, ys, yt, zs /*zt*/;    /* projection scale and translate */
  27. register float t0, t1, t2, t3, t4, t5;    /* temps */
  28. register float one = 1.0;
  29.  
  30. /* load up local projection matrix */
  31. xs = *(prj+0); xt = *(prj+1);
  32. ys = *(prj+2); yt = *(prj+3);
  33. zs = *(prj+4); /* zt = *(prj+5); later */
  34.  
  35. /* load up local transform matrix */
  36. xx = *(mtx+0 ); xy = *(mtx+1 ); xz = *(mtx+2 ); xw = *(mtx+3 );
  37. yx = *(mtx+4 ); yy = *(mtx+5 ); yz = *(mtx+6 ); yw = *(mtx+7 );
  38. zx = *(mtx+8 ); zy = *(mtx+9 ); zz = *(mtx+10); zw = *(mtx+11);
  39. wx = *(mtx+12); wy = *(mtx+13); wz = *(mtx+14); ww = *(mtx+15);
  40.  
  41. /* initialize accumulated flags */
  42. flag_or = 0;
  43. flag_and = -1;
  44.  
  45. do {
  46. #define wi    t4
  47.     wi = vpi[3];    /* wi */
  48. #define xi    t5
  49.     xi = vpi[0];    /* xi */
  50.  
  51.     /* calculate 4x4 transform, use as few regs as possible */
  52.     wo = wi*ww; xo = wi*wx; yo = wi*wy; zo = wi*wz;
  53. #define yi    t4
  54.     yi = vpi[1];    /* yi */
  55.  
  56.     t0 = xi*xw; t1 = xi*xx; t2 = xi*xy; t3 = xi*xz;
  57. #define zi    t5
  58.     zi = vpi[2];    /* zi */
  59.     wo += t0; xo += t1; yo += t2; zo += t3;
  60.  
  61.     t0 = yi*yw; t1 = yi*yx; t2 = yi*yy; t3 = yi*yz;
  62.     wo += t0; xo += t1; yo += t2; zo += t3;
  63.  
  64.     t0 = zi*zw; t1 = zi*zx; t2 = zi*zy; t3 = zi*zz;
  65.     wo += t0; xo += t1; yo += t2; zo += t3;
  66.  
  67. #define winv    t0
  68.     winv = one / wo;
  69.  
  70.     {
  71.     /* put values on stack so we can get them as integers */
  72.     float sxo, syo, szo, swo;    /* stacked output values */
  73.  
  74.     swo = wo;
  75.     sxo = xo;
  76.     syo = yo;
  77.     szo = zo;
  78.  
  79. #define zt    t1
  80.     /* ready for this now */
  81.     zt =    prj[5];
  82.  
  83.     /* interleave clip checking with projection to DC */
  84.     xo *= xs;
  85.     yo *= ys;
  86.     zo *= zs;
  87.  
  88.     /* branch-free clip checker*/
  89.     ti0 = FI(swo);
  90.     s = ti0 & ~sign;      /* abs(w) */
  91.  
  92.     ti0 = FI(sxo);
  93.     t = ti0 & ~sign;      /* abs(x) */
  94.     u = s - t;        /* compare to abs(w) */
  95.     u = (unsigned int)u >> 31; /* extract sign, 1 is abs(x) > abs(w) */
  96.     t = (unsigned int)ti0 >> 31; /* x sign */
  97.     flag = u << t;         /* bit 0: x pos bit 1: x neg */
  98.  
  99.     xo *= winv;
  100.     yo *= winv;
  101.     zo *= winv;
  102.  
  103.     ti0 = FI(syo);
  104.     t = ti0 & ~sign;      /* abs(y) */
  105.     u = s - t;        /* compare to w */
  106.     u = (unsigned int)u >> 31;    /* extract sign, 1 is abs(y) > w */
  107.     t = (unsigned int)ti0 >> 31;      /* y sign */
  108.     t += 2;
  109.     t = u << t;        /* bit 2: y pos bit 3: y neg */
  110.     flag |= t;
  111.  
  112.     xo += xt;
  113.     yo += yt;
  114.     zo += zt;
  115.  
  116.     ti0 = FI(szo);
  117.     t = ti0 & ~sign;      /* abs(z) */
  118.     u = s - t;        /* compare to w */
  119.     u = (unsigned int)u >> 31;    /* extract sign, 1 is abs(z) > w */
  120.     t = (unsigned int)ti0 >> 31;      /* z sign */
  121.     t += 4;
  122.     t = u << t;        /* bit 4: z pos bit 5: z neg */
  123.     flag |= t;
  124.  
  125.     }
  126.  
  127.     flag_or |= flag;
  128.     flag_and &= flag;
  129.  
  130.     *(vpo+0) = xo;
  131.     *(vpo+1) = yo;
  132.     *(vpo+2) = zo;
  133.     *pf = flag;
  134.  
  135.     vpi += visiz;
  136.     vpo += vosiz;
  137.     pf++;
  138. } while (--vc > 0);
  139.  
  140. *(pa+0) = flag_or;
  141. *(pa+1) = flag_and;
  142.  
  143. return;
  144. }
  145.